home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
borland
/
jnfb88.zip
/
TSORT.ZIP
/
UNIVDIR.PRO
< prev
Wrap
Text File
|
1987-10-20
|
6KB
|
207 lines
/* UNIVDIR.PRO
This routine collects a database of all files in
all subdirectories on a disk, sorts the filenames, and
then uses the result to output a formatted, sorted list of
files to the screen and an ASCII file.
Copyright 1987, by Alex Lane
This program uses modified routines from the Turbo Prolog
Toolbox, which is Copyright 1987, Borland International.
*/
domains
file = f1; f2
charlist = char *
database
file(string,string,integer,real,string,integer,integer,real,
integer,integer,integer)
path(string) /* used to build a pseudo-stack of subdirectories */
t(integer) /* this functor provides a 'tag' identification */
predicates
univdir(string)
post_or_record(string,integer,integer,integer,real,integer,
integer,real,string)
tag(integer)
tokenize_filename(string,string,string)
list_text(string,charlist) /* (i,o) */
list_text1(string,charlist,string)
append(charlist,charlist,charlist)
pretty_out(file,file)
repeat
goal
makewindow(1,7,7,"Hard disk directory list sorter",0,0,25,80),
asserta(t(1)), /* initialize the tag index to 1 */
/* The file TEST.DAT will contain 18-byte records consisting of
a 12-byte file name, a 4-digit tag identification, and a
carriage-return-line-feed comhbination
*/
openwrite(f1,"TEST.DAT"),
/* the argument to univdir() specifies where to START the
directory search. Examples:
"" - searches the default disk
"C:" - searches the C: disk (typically the hard disk)
"\\PROLOG" - searches the subdirectory \PROLOG on the
default disk (recall that the '\' character
must appear twice in a string since it is the
escape character).
*/
univdir("C:"),
closefile(f1),
retract(t(_)), /* this fella's job is done */
/* we now make a system call to DOS, which will run the
program RDSRT.COM for us. RDSRT.COM already expects to find
a file called TEST.DAT in the default directory, and after
processing, will leave a file called TEST.OUT for us to use
when control returns to this program.
*/
system("RDSRT"),
clearwindow,
openread(f1,"TEST.OUT"),
/* we will write the sorted hard disk file information to the
file MYFILES.TXT on the default disk.
*/
openwrite(f2,"MYFILES.DAT"),
readdevice(f1),
writedevice(f2),
pretty_out(f1,f2),
readdevice(keyboard),
writedevice(screen), /* restore the console devices for i/o */
closefile(f1),
closefile(f2),
deletefile("TEST.DAT"),
deletefile("TEST.OUT"), /* clean up a little before exiting */
write("\n\nDone. The sorted file listing is in MYFILES.DAT").
/* FINDMATC.PRO is a modified excerpt of the Turbo Toolbox file
BIOS.PRO Modifications to support file sizes greater 32767.
*/
include "findmatc.pro"
clauses
/* The univdir() predicate is the workhorse of the the program. It
calls the Toolbox predicate findmatch() to retrieve filenames. If
the file name is the name of a subdirectory, the predicate
post_or_record() asserts the subdirectory name using the path()
functor. Otherwise, the filename is prepared for sorting and
asserted through the file() functor.
*/
univdir(Path) :-
concat(Path,"\\*.*",SearchSpec),
findmatch(SearchSpec,63,
Filename,FileAttr,FileH,FileM,FileY,
FileMo,FileD,FileSize),
Filename <> ".", /* ignore the DOS . and .. file entries */
Filename <> "..",
post_or_record(Filename,FileAttr,FileH,FileM,FileY,FileMo,
FileD,FileSize,Path),
fail. /* we use fail here to force backtracking to
findmatch() */
/* Once we've exhausted the entries in any given directory, this call
to univdir() sets us down another path to a new subdirectory by
retracting a path name through the path() functor.
*/
univdir(_):-
retract(path(NewPath)),
write("!"),
univdir(NewPath).
/* if we've run out of entries and out of path names, we're done
scanning the directory on the disk.
*/
univdir(_):- !.
post_or_record(Name,16,_,_,_,_,_,_,Path):-
concat(Path,"\\",Halfway),
concat(Halfway,Name,NewPath),
asserta(path(NewPath)).
post_or_record(Name,Attr,Hour,Min,Year,Mo,Day,Size,Path):-
Attr <> 16,
write("#"),
tokenize_filename(Name,File,Ext),
writedevice(f1),
tag(A),
writef("%-8%-4%4\n", File,Ext,A),
writedevice(screen),
assertz(file(File,Ext,Attr,Size,Path,Hour,Min,Year,Mo,Day,A)),
!.
/* I'd like to extract the file and extension parts of the name so
as to be able to uniformly sort on an 8-char file and 3-char
extension, with both the file and extension flush left. In other
words, instead of having names like:
C.BAT
FOO.BAR
DISKDOPE.C
README
I'd like to have:
C .BAT
FOO .BAR
DISKDOPE.C
README .
*/
tokenize_filename(Name,File,Ext) :-
list_text(Name,Namelist),
append(A,['.'|T],Namelist),
B = [ '.' | T ],
list_text(File,A),
list_text(Ext,B).
tokenize_filename(Name,Name,".").
list_text("",[]) :- !.
list_text(String,[H|T]) :-
bound(String),
frontchar(String,H,Rest),
list_text(Rest,T).
list_text(String,[H|T]) :-
bound(H),
list_text1("",[H|T],String).
list_text1(A,[],A) :- !.
list_text1(A,[H|T],Out) :-
str_char(Hs,H),
concat(A,Hs,AHs),
list_text1(AHs,T,Out).
tag(N) :-
retract(t(A)),
N = A + 1,
asserta(t(N)), ! .
append([],L,L).
append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).
/* The pretty_out() predicate lets me output a nicely formatted list
of file information.
*/
pretty_out(In,Out) :-
repeat,
readint(A),
retract(file(File,Ext,_,Size,Path,Hour,Min,Year,Mo,Day,A)),
writef("%-8%-4 %6.0f %02:%02 %02-%02-%4 %-24\n",
File,Ext,Size,Hour,Min,Mo,Day,Year,Path),
writedevice(screen),
write("%"),
writedevice(Out),
eof(In).
repeat.
repeat:- repeat.